package com.richapp.launcher.serialport.infrared.message;

import android.util.Log;

import com.richapp.launcher.serialport.infrared.abstracts.AMessage;
import com.richapp.net.util.HexTool;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * Created by jack on 2015/4/3 0003.
 */
public class ControlMessage extends AMessage {

    /**
     * 设备类型 一个字节
     * 0x01 电视机
     * 0x02 网络电视
     * 0x03 机顶盒
     * 0x04 网络盒子
     * 0x05 空调
     * 0x06 DVD
     * 0x07 电风扇
     * 0x08 单反
     * 0x09 音箱
     * 0x0A 投影仪
     * 0x30 学习的数据
     */
    private byte deviceType = 0x01;

    /**
     * 设备ID 一个字节 0x00 - 0xFF,默认0x00
     */
    private byte deviceId = 0x00;

    /**
     * 遥控数据 N bytes
     */
    private byte[] controlData;

    /**
     * 发送的结果,5个字节: 类型+长度+结果+校验
     * 操作结果，一个字节
     * 0x01 接收成功
     * 0x02 接收失败
     * 0x03 操作超时
     */
    private byte[] result = null;

    public static final long TIME_OUT_CONTROL = 1000;

    private String userName;
    private long controlKey = 0;

    public ControlMessage(){

    }

    public byte getDeviceType() {
        return deviceType;
    }

    public void setDeviceType(byte deviceType) {
        this.deviceType = deviceType;
    }

    public byte getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(byte deviceId) {
        this.deviceId = deviceId;
    }

    public byte[] getControlData() {
        return controlData;
    }

    public void setControlData(byte[] controlData) {
        this.controlData = controlData;
    }

    public byte[] getResult() {
        return result;
    }

    public void setResult(byte[] result) {
        this.result = result;
    }

    @Override
    public void doCheckData() {
        int check = getType();
        for(byte b : getLength()){
            check += b;
        }
        check = check + getDeviceType() + getDeviceId();
        for(byte b : controlData){
            check += b;
        }
        check  = check % 256;
        setCheck((byte)check);

        ByteBuffer byteBuffer = ByteBuffer.allocate(2+controlData.length);
        byteBuffer.put(deviceType);
        byteBuffer.put(deviceId);
        byteBuffer.put(controlData);

        byte[] array = byteBuffer.array();
        setSendData(array);

        byteBuffer = ByteBuffer.allocate( 1 + 2 + array.length + 1 );
        byteBuffer.put(getType());
        byteBuffer.put(getLength());
        byteBuffer.put(array);
        byteBuffer.put(getCheck());

        array = byteBuffer.array();
        Log.d("DEBUG","合成的数据:"+ HexTool.ByteArrToHex(array));
        setAllData(array);
    }

    @Override
    public void doSendData() {
        try {
            Log.d("DEBUG","写入红外控制数据");
            getDataOutputStream().write(getAllData());
            getDataOutputStream().flush();
            setStartTime(System.currentTimeMillis());
            doGetResult();
        } catch (IOException e) {
            Log.d("DEBUG", "红外控制写入错误:" + e.getMessage());
        }
    }

    @Override
    public void doGetResult() {
        try{
            if(getDataInputStream().available() > 4){
                byte[] buffer = new byte[5];
                getDataInputStream().read(buffer);

                int check = 0;
                for(int i = 0; i < buffer.length-1 ;i++){
                    check += buffer[i];
                }
                Log.d("DEBUG","红外控制反馈数据:"+HexTool.ByteArrToHex(buffer));
                if(check != buffer[4]){
                    Log.d("DEBUG", "红外控制读取校验失败:"+ "checkValue:"+check+ "|lastByte:"+buffer[4]);
                }
                setResult(buffer);
                setStopTime(System.currentTimeMillis());
                final ControlMessage controlMessage = this;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        getInfraredMessageListener().onInfraredMessage(controlMessage);
                    }
                }).start();
            }
        }catch (Exception e){
            Log.d("DEBUG", "红外控制读取错误:" + e.getMessage());
        }
    }

    @Override
    public boolean isTimeOut() {
        long currentTime = System.currentTimeMillis();
        long value = currentTime - getStartTime();
        boolean flag = value > TIME_OUT_CONTROL;
        if(flag){
            Log.d("DEBUG", "红外控制发射超时");
        }
        return flag;
    }

    @Override
    public boolean isResultOk() {
        if(getResult() != null){
            return true;
        }
        return false;
    }

    @Override
    public byte getType() {
        return 0x01;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public long getControlKey() {
        return controlKey;
    }

    public void setControlKey(long controlKey) {
        this.controlKey = controlKey;
    }
}
